#ifndef PFS_TCP_H
#define PFS_TCP_H

#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <unistd.h>
#include <stdint.h>
#include "ThreadPool.h"
#include "util.h"
#include "config.h"
#include <event.h>


#include <string>
#include <sstream>
#include <set>
using namespace std;
#define max_epoll_size 10000
namespace PFS
{

    typedef struct sockaddr* SA;
    class Tcp
    {
        public:
            Tcp();
            Tcp(int fd);
            Tcp(const Tcp &ln)
            { sock_fd = ln.sock_fd; }
            virtual ~Tcp();
            int Listen(int port);
            Tcp* Accept();
            int accept_ret_fd();
            int Connect(const struct sockaddr_in *romote_addr,bool nonblocking = false);

            inline bool is_active() const
            { return sock_fd >= 0;}
            inline bool is_active()
            { return sock_fd >= 0;}
            void set_fd(int fd);
            int get_peer_name(struct sockaddr *peer_addr,int len);
            string get_peer_name();
            string get_sock_name();
            int Send(void* buf,int len);
            int Recv(void* buf,int len);
            int peek(void* buf, int len);
            void Close();
            void setup_socket();
            inline int get_fd(){ return sock_fd;}
            inline int get_fd() const { return sock_fd;}
        private:
            int sock_fd;
    };

    class TcpServer
    {
        public:
            TcpServer(int port);
            TcpServer(const Tcp &tcp, int port);
            virtual ~TcpServer();
            void setup_thread(int num, thread_fun fun);
            static void on_new_client(int fd, short flags, void *arg);
            int start();
            int stop();
        private:
            Tcp server;
            Job* job;
            struct event_base *base;
            struct event ev;
            int port;
            ThreadPool *thread_pool;
    };
}
#endif
